<?php
/**
 * @purpose
 * @Author: Madou
 * @Time  : 2022/7/28 22:48
 */

namespace App\Models\Plane\PlaneOrders\Repositories;

use App\Models\Plane\PlaneOrders\PlaneOrder;
use App\Models\Plane\PlaneOrders\Repositories\Interfaces\PlaneOrderRepositoryInterface;
use App\Trip\Orders\TripOrderState;
use Illuminate\Support\Collection;

class TheChangeOrderStateChanged
{
    private PlaneOrder $change_order_info;
    private PlaneOrder $origin_order_info;
    private int        $new_order_state;
    private int        $origin_order_passenger_order_state;
    private int        $origin_order_info_order_state;
    private int        $origin_order_info_show_state;
    private int        $common_order_state;
    private Collection $other_changed_orders;
    private int        $origin_order_info_change_flag;
    private PlaneOrder $commonOrderSubOrder;
    private int        $show_state;
    private int        $delete_state;
    private int        $last_changed_order_show_state;

    public function __construct(PlaneOrder $change_order_info, PlaneOrder $origin_order_info, int $new_order_state)
    {
        $this->change_order_info             = $change_order_info;
        $this->commonOrderSubOrder           = $this->change_order_info;
        $this->origin_order_info             = $origin_order_info;
        $this->new_order_state               = $new_order_state;
        $this->show_state                    = 1;
        $this->delete_state                  = 0;
        $this->origin_order_info_show_state  = 0;
        $this->common_order_state            = $this->new_order_state;
        $this->origin_order_info_change_flag = $origin_order_info->getChangeFlag();
        $planeOrdersRepo                     = app(PlaneOrderRepositoryInterface::class);
        $this->other_changed_orders          = $planeOrdersRepo->getOtherChangedOrders($this->change_order_info, false);
        $this->calc();
    }

    public function getOtherChangedOrders(): Collection
    {
        return $this->other_changed_orders;
    }

    /**
     * 根据 当前订单的状态计算 原单的新状态
     *
     * @return void
     */
    private function calc(): void
    {

        $has_last_other_changed_order = $this->getLastOtherChangedOrder();
        switch ($this->new_order_state) {
            case TripOrderState::ORDER_STATE_CHANGE_WAITING_PAY:
            case TripOrderState::ORDER_STATE_CHANGING:
                $this->origin_order_passenger_order_state = $this->new_order_state;
                $this->origin_order_info_order_state      = $this->new_order_state;
                $this->origin_order_info_change_flag      = TripOrderState::ORDER_CHANGE_FLAG_ORIGIN;
                $this->origin_order_info_show_state       = 0;
                $this->last_changed_order_show_state      = 0;
                break;
            case TripOrderState::ORDER_STATE_CHANGED:
                $this->origin_order_passenger_order_state = TripOrderState::ORDER_STATE_CHANGED;
                $this->origin_order_info_order_state      = TripOrderState::ORDER_STATE_CHANGED;
                $this->origin_order_info_change_flag      = TripOrderState::ORDER_CHANGE_FLAG_ORIGIN;
                $this->origin_order_info_show_state       = 0;
                $this->last_changed_order_show_state      = 0;
                if ($this->hasChangedFailedOtherOrders()) {
                    $this->common_order_state = TripOrderState::ORDER_STATE_CHANGED_PART;
                } elseif ($this->hasChangedAndRefundedOtherOrders()) {
                    $this->common_order_state = TripOrderState::ORDER_STATE_CHANGED_HAS_REFUNDED;
                }
                break;
            case TripOrderState::ORDER_STATE_CHANGE_FAILED:
                /**
                 * 改签失败喽 如果没有其他改签订单 总单显示失败
                 * 如果有显示部分改签成功
                 */
                $this->origin_order_passenger_order_state = TripOrderState::ORDER_STATE_TICKETED;
                $this->origin_order_info_order_state      = TripOrderState::ORDER_STATE_TICKETED;
                $this->origin_order_info_change_flag      = TripOrderState::ORDER_CHANGE_FLAG_ORIGIN;
                $this->origin_order_info_show_state       = 0;
                $this->last_changed_order_show_state      = 0;
                if (!$has_last_other_changed_order) {
                    $this->common_order_state           = TripOrderState::ORDER_STATE_TICKETED;
                    $this->commonOrderSubOrder          = $this->origin_order_info;
                    $this->origin_order_info_show_state = 1;
                    $this->show_state                   = 0;
                    $this->delete_state                 = 1;
                } else if ($this->hasChangedAndRefundedOtherOrders()) {
                    $this->common_order_state = TripOrderState::ORDER_STATE_CHANGED_HAS_REFUNDED;
                } else if ($this->hasChangedSuccessOtherOrders()) {
                    $this->common_order_state = TripOrderState::ORDER_STATE_CHANGED_PART;
                }
                break;
            case TripOrderState::ORDER_STATE_MANUAL_CANCEL:
            case TripOrderState::ORDER_STATE_AUTO_CANCEL:
                /**
                 * 仅仅改签订单取消时还原总单
                 *
                 */
                if (!$has_last_other_changed_order) {
                    $this->origin_order_passenger_order_state = TripOrderState::ORDER_STATE_TICKETED;
                    $this->origin_order_info_order_state      = TripOrderState::ORDER_STATE_TICKETED;
                    $this->origin_order_info_change_flag      = TripOrderState::ORDER_CHANGE_FLAG_NONE;
                    $this->origin_order_info_show_state       = 1;
                    $this->last_changed_order_show_state      = 0;
                    $this->commonOrderSubOrder                = $this->origin_order_info;
                } else {
                    /**
                     * 此处应为最后一次已改签出票后的订单
                     */
                    $this->commonOrderSubOrder                = $has_last_other_changed_order;
                    $this->origin_order_passenger_order_state = TripOrderState::ORDER_STATE_TICKETED;
                    $this->origin_order_info_order_state      = TripOrderState::ORDER_STATE_TICKETED;
                    $this->origin_order_info_change_flag      = TripOrderState::ORDER_CHANGE_FLAG_ORIGIN;
                    $this->origin_order_info_show_state       = 0;
                    $this->last_changed_order_show_state      = 1;
                }
                /**
                 * 新单显示状态 -》 隐藏并删除
                 */
                $this->show_state   = 0;
                $this->delete_state = 1;
                break;
        }
    }

    /**
     * 最后一笔改签的订单 不含删除
     *
     * @return PlaneOrder|null
     */
    public function getLastOtherChangedOrder(): ?PlaneOrder
    {
        return $this->other_changed_orders->first() ?: null;
    }

    private function hasChangedFailedOtherOrders(): bool
    {
        return $this->other_changed_orders->where('order_state', TripOrderState::ORDER_STATE_CHANGE_FAILED)->count() > 0;
    }

    private function hasChangedAndRefundedOtherOrders(): bool
    {
        return $this->other_changed_orders->where('order_state', TripOrderState::ORDER_STATE_REFUNDED)->count() > 0;
    }

    private function hasChangedSuccessOtherOrders(): bool
    {
        return $this->other_changed_orders->where('order_state', TripOrderState::ORDER_STATE_CHANGED)->count() > 0;
    }

    public function getChangeOrderState(): int
    {
        return $this->new_order_state;
    }

    public function getChangeOrderShowState(): int
    {
        return $this->show_state;
    }

    public function getChangeOrderWillDelete(): int
    {
        return $this->getChangeOrderDeleteState() == 1;
    }

    public function getChangeOrderDeleteState(): int
    {
        return $this->delete_state;
    }

    public function getOriginOrderState(): int
    {
        return $this->origin_order_info_order_state;
    }

    public function getLastChangedOrderShowState(): int
    {
        return $this->last_changed_order_show_state;
    }

    public function getOriginOrderShowState(): int
    {
        return $this->origin_order_info_show_state;
    }

    public function getOriginOrderChangeFlag(): int
    {
        return $this->origin_order_info_change_flag;
    }

    public function getCommonOrderState(): int
    {
        return $this->common_order_state;
    }

    public function getCommonOrderSubOrder(): PlaneOrder
    {
        return $this->commonOrderSubOrder;
    }

    public function getNeedUpdateOriginPassengerOrderState(): int
    {
        return $this->origin_order_passenger_order_state;
    }

    public function getNeedUpdateOriginPassengers(): array
    {
        $passengers        = [];
        $origin_passengers = $this->getOriginOrderPassengers();
        foreach ($this->getChangeOrderPassengers() as $passenger) {
            $op = $origin_passengers->where('passenger_id', $passenger->getPassengerId())
                                    ->firstWhere('sequence', $passenger->getSequence());
            if (!$op) {
                continue;
            }
            $passengers[] = $op;
        }
        return $passengers;
    }

    private function getOriginOrderPassengers(): Collection
    {
        return $this->origin_order_info->getPassengers();
    }

    private function getChangeOrderPassengers(): Collection
    {
        return $this->change_order_info->getPassengers();
    }
}